// -*- C++ -*-
/****************************************************************************
 *
 *  class TSurfaceNet
 *
 ****************************************************************************
 *
 *  File         :  TSurfaceNet.cc
 *
 *  Purpose      :
 *
 ****************************************************************************
 *
 *  started      :  3  Jan 95    Robert Schweikert
 *  last change  :  20 Jan 95
 *
 ****************************************************************************/

#include "TSurfaceNet.h"

// This defines the three tables that are used to construct a
// surface net from a 3D binary (voxel) data set in TNetExtractor.cc
// This is derived from the two files  made with mathematica.

const int tr_direct[6][8] = {{1, -1, 3, -1, 5, -1, 7, -1}, {-1, 0, -1, 2, -1, 4, -1, 6}, {2, 3, -1, -1, 6, 7, -1, -1},
                     {-1, -1, 0, 1, -1, -1, 4, 5}, {4, 5, 6, 7, -1, -1, -1, -1}, {-1, -1, -1, -1, 0, 1, 2, 3}};

const TNetExtractor::t1entry pt1[256] =
  {
    {0,    1,    {0}},
    {1,    1,    {1}},
    {2,    1,    {2}},
    {3,    1,    {3}},
    {4,    1,    {4}},
    {5,    1,    {5}},
    {6,    2,    {2,    4}},
    {7,    1,    {7}},
    {8,    1,    {8}},
    {9,    2,    {1,    8}},
    {10,    1,    {10}},
    {11,    1,    {11}},
    {12,    1,    {12}},
    {13,    1,    {13}},
    {14,    1,    {14}},
    {15,    1,    {15}},
    {16,    1,    {16}},
    {17,    1,    {17}},
    {18,    2,    {2,    16}},
    {19,    1,    {19}},
    {20,    2,    {4,    16}},
    {21,    1,    {21}},
    {22,    3,    {2,    4,    16}},
    {23,    1,    {23}},
    {24,    2,    {16,    8}},
    {25,    2,    {17,    8}},
    {26,    2,    {10,    16}},
    {27,    1,    {27}},
    {28,    2,    {12,    16}},
    {29,    1,    {29}},
    {30,    2,    {14,    16}},
    {31,    1,    {31}},
    {32,    1,    {32}},
    {33,    2,    {1,    32}},
    {34,    1,    {34}},
    {35,    1,    {35}},
    {36,    2,    {4,    32}},
    {37,    2,    {5,    32}},
    {38,    2,    {34,    4}},
    {39,    1,    {39}},
    {40,    2,    {8,    32}},
    {41,    3,    {1,    8,    32}},
    {42,    1,    {42}},
    {43,    1,    {43}},
    {44,    2,    {12,    32}},
    {45,    2,    {13,    32}},
    {46,    1,    {46}},
    {47,    1,    {47}},
    {48,    1,    {48}},
    {49,    1,    {49}},
    {50,    1,    {50}},
    {51,    1,    {51}},
    {52,    2,    {48,    4}},
    {53,    1,    {53}},
    {54,    2,    {50,    4}},
    {55,    1,    {55}},
    {56,    2,    {48,    8}},
    {57,    2,    {49,    8}},
    {58,    1,    {58}},
    {59,    1,    {59}},
    {60,    2,    {12,    48}},
    {61,    1,    {61}},
    {62,    1,    {62}},
    {63,    1,    {63}},
    {64,    1,    {64}},
    {65,    2,    {1,    64}},
    {66,    2,    {2,    64}},
    {67,    2,    {3,    64}},
    {68,    1,    {68}},
    {69,    1,    {69}},
    {70,    2,    {68,    2}},
    {71,    1,    {71}},
    {72,    2,    {8,    64}},
    {73,    3,    {1,    8,    64}},
    {74,    2,    {10,    64}},
    {75,    2,    {11,    64}},
    {76,    1,    {76}},
    {77,    1,    {77}},
    {78,    1,    {78}},
    {79,    1,    {79}},
    {80,    1,    {80}},
    {81,    1,    {81}},
    {82,    2,    {80,    2}},
    {83,    1,    {83}},
    {84,    1,    {84}},
    {85,    1,    {85}},
    {86,    2,    {84,    2}},
    {87,    1,    {87}},
    {88,    2,    {80,    8}},
    {89,    2,    {81,    8}},
    {90,    2,    {10,    80}},
    {91,    1,    {91}},
    {92,    1,    {92}},
    {93,    1,    {93}},
    {94,    1,    {94}},
    {95,    1,    {95}},
    {96,    2,    {32,    64}},
    {97,    3,    {1,    32,    64}},
    {98,    2,    {34,    64}},
    {99,    2,    {35,    64}},
    {100,    2,    {68,    32}},
    {101,    2,    {69,    32}},
    {102,    2,    {34,    68}},
    {103,    1,    {103}},
    {104,    3,    {8,    32,    64}},
    {105,    4,    {1,    8,    32,    64}},
    {106,    2,    {42,    64}},
    {107,    2,    {43,    64}},
    {108,    2,    {76,    32}},
    {109,    2,    {77,    32}},
    {110,    1,    {110}},
    {111,    1,    {111}},
    {112,    1,    {112}},
    {113,    1,    {113}},
    {114,    1,    {114}},
    {115,    1,    {115}},
    {116,    1,    {116}},
    {117,    1,    {117}},
    {118,    1,    {118}},
    {119,    1,    {119}},
    {120,    2,    {112,    8}},
    {121,    2,    {113,    8}},
    {122,    1,    {122}},
    {123,    1,    {123}},
    {124,    1,    {124}},
    {125,    1,    {125}},
    {126,    2,    {127,    254}},
    {127,    1,    {127}},
    {128,    1,    {128}},
    {129,    2,    {1,    128}},
    {130,    2,    {2,    128}},
    {131,    2,    {3,    128}},
    {132,    2,    {4,    128}},
    {133,    2,    {5,    128}},
    {134,    3,    {2,    4,    128}},
    {135,    2,    {7,    128}},
    {136,    1,    {136}},
    {137,    2,    {136,    1}},
    {138,    1,    {138}},
    {139,    1,    {139}},
    {140,    1,    {140}},
    {141,    1,    {141}},
    {142,    1,    {142}},
    {143,    1,    {143}},
    {144,    2,    {16,    128}},
    {145,    2,    {17,    128}},
    {146,    3,    {2,    16,    128}},
    {147,    2,    {19,    128}},
    {148,    3,    {4,    16,    128}},
    {149,    2,    {21,    128}},
    {150,    4,    {2,    4,    16,    128}},
    {151,    2,    {23,    128}},
    {152,    2,    {136,    16}},
    {153,    2,    {17,    136}},
    {154,    2,    {138,    16}},
    {155,    1,    {155}},
    {156,    2,    {140,    16}},
    {157,    1,    {157}},
    {158,    2,    {142,    16}},
    {159,    1,    {159}},
    {160,    1,    {160}},
    {161,    2,    {160,    1}},
    {162,    1,    {162}},
    {163,    1,    {163}},
    {164,    2,    {160,    4}},
    {165,    2,    {5,    160}},
    {166,    2,    {162,    4}},
    {167,    1,    {167}},
    {168,    1,    {168}},
    {169,    2,    {168,    1}},
    {170,    1,    {170}},
    {171,    1,    {171}},
    {172,    1,    {172}},
    {173,    1,    {173}},
    {174,    1,    {174}},
    {175,    1,    {175}},
    {176,    1,    {176}},
    {177,    1,    {177}},
    {178,    1,    {178}},
    {179,    1,    {179}},
    {180,    2,    {176,    4}},
    {181,    1,    {181}},
    {182,    2,    {178,    4}},
    {183,    1,    {183}},
    {184,    1,    {184}},
    {185,    1,    {185}},
    {186,    1,    {186}},
    {187,    1,    {187}},
    {188,    1,    {188}},
    {189,    2,    {253,    191}},
    {190,    1,    {190}},
    {191,    1,    {191}},
    {192,    1,    {192}},
    {193,    2,    {192,    1}},
    {194,    2,    {192,    2}},
    {195,    2,    {3,    192}},
    {196,    1,    {196}},
    {197,    1,    {197}},
    {198,    2,    {196,    2}},
    {199,    1,    {199}},
    {200,    1,    {200}},
    {201,    2,    {200,    1}},
    {202,    1,    {202}},
    {203,    1,    {203}},
    {204,    1,    {204}},
    {205,    1,    {205}},
    {206,    1,    {206}},
    {207,    1,    {207}},
    {208,    1,    {208}},
    {209,    1,    {209}},
    {210,    2,    {208,    2}},
    {211,    1,    {211}},
    {212,    1,    {212}},
    {213,    1,    {213}},
    {214,    2,    {212,    2}},
    {215,    1,    {215}},
    {216,    1,    {216}},
    {217,    1,    {217}},
    {218,    1,    {218}},
    {219,    2,    {251,    223}},
    {220,    1,    {220}},
    {221,    1,    {221}},
    {222,    1,    {222}},
    {223,    1,    {223}},
    {224,    1,    {224}},
    {225,    2,    {224,    1}},
    {226,    1,    {226}},
    {227,    1,    {227}},
    {228,    1,    {228}},
    {229,    1,    {229}},
    {230,    1,    {230}},
    {231,    2,    {239,    247}},
    {232,    1,    {232}},
    {233,    2,    {232,    1}},
    {234,    1,    {234}},
    {235,    1,    {235}},
    {236,    1,    {236}},
    {237,    1,    {237}},
    {238,    1,    {238}},
    {239,    1,    {239}},
    {240,    1,    {240}},
    {241,    1,    {241}},
    {242,    1,    {242}},
    {243,    1,    {243}},
    {244,    1,    {244}},
    {245,    1,    {245}},
    {246,    1,    {246}},
    {247,    1,    {247}},
    {248,    1,    {248}},
    {249,    1,    {249}},
    {250,    1,    {250}},
    {251,    1,    {251}},
    {252,    1,    {252}},
    {253,    1,    {253}},
    {254,    1,    {254}},
    {255,    1,    {0}}
  };

// Subtracting 1 from each direction translates Mathematica indices to
// C++ indices

const TNetExtractor::t2entry pt2[256] =
  {
    {0,    1,    {-1},    {-1}},
    {1,    3,    {3 - 1, 5 - 1, 1 - 1},    {0, 0, 0}},
    {2,    3,    {5 - 1, 3 - 1, 2 - 1},    {1, 1, 1}},
    {3,    4,    {3 - 1, 2 - 1, 5 - 1, 1 - 1},    {0, 1, 1, 0}},
    {4,    3,    {5 - 1, 4 - 1, 1 - 1},    {2, 2, 2}},
    {5,    4,    {3 - 1, 5 - 1, 4 - 1, 1 - 1},    {0, 0, 2, 2}},
    {6,    1,    {-1},    {-1}},
    {7,    5,    {3 - 1, 2 - 1, 5 - 1, 4 - 1, 1 - 1},    {0, 1, 1, 2, 2}},
    {8,    3,    {4 - 1, 5 - 1, 2 - 1},    {3, 3, 3}},
    {9,    1,    {-1},    {-1}},
    {10,    4,    {4 - 1, 5 - 1, 3 - 1, 2 - 1},    {3, 3, 1, 1}},
    {11,    5,    {3 - 1, 2 - 1, 4 - 1, 5 - 1, 1 - 1},    {0, 1, 3, 3, 0}},
    {12,    4,    {5 - 1, 2 - 1, 4 - 1, 1 - 1},    {2, 3, 3, 2}},
    {13,    5,    {3 - 1, 5 - 1, 2 - 1, 4 - 1, 1 - 1},    {0, 0, 3, 3, 2}},
    {14,    5,    {5 - 1, 3 - 1, 2 - 1, 4 - 1, 1 - 1},    {2, 1, 1, 3, 2}},
    {15,    4,    {3 - 1, 2 - 1, 4 - 1, 1 - 1},    {0, 1, 3, 2}},
    {16,    3,    {6 - 1, 3 - 1, 1 - 1},    {4, 4, 4}},
    {17,    4,    {6 - 1, 3 - 1, 5 - 1, 1 - 1},    {4, 4, 0, 0}},
    {18,    1,    {-1},    {-1}},
    {19,    5,    {6 - 1, 3 - 1, 2 - 1, 5 - 1, 1 - 1},    {4, 4, 1, 1, 0}},
    {20,    1,    {-1},    {-1}},
    {21,    5,    {6 - 1, 3 - 1, 5 - 1, 4 - 1, 1 - 1},    {4, 4, 0, 2, 2}},
    {22,    1,    {-1},    {-1}},
    {23,    6,    {6 - 1, 3 - 1, 2 - 1, 5 - 1, 4 - 1, 1 - 1},    {4, 4, 1, 1, 2, 2}},
    {24,    1,    {-1},    {-1}},
    {25,    1,    {-1},    {-1}},
    {26,    1,    {-1},    {-1}},
    {27,    6,    {6 - 1, 3 - 1, 2 - 1, 4 - 1, 5 - 1, 1 - 1},    {4, 4, 1, 3, 3, 0}},
    {28,    1,    {-1},    {-1}},
    {29,    6,    {6 - 1, 3 - 1, 5 - 1, 2 - 1, 4 - 1, 1 - 1},    {4, 4, 0, 3, 3, 2}},
    {30,    1,    {-1},    {-1}},
    {31,    5,    {6 - 1, 3 - 1, 2 - 1, 4 - 1, 1 - 1},    {4, 4, 1, 3, 2}},
    {32,    3,    {3 - 1, 6 - 1, 2 - 1},    {5, 5, 5}},
    {33,    1,    {-1},    {-1}},
    {34,    4,    {5 - 1, 3 - 1, 6 - 1, 2 - 1},    {1, 1, 5, 5}},
    {35,    5,    {3 - 1, 6 - 1, 2 - 1, 5 - 1, 1 - 1},    {0, 5, 5, 1, 0}},
    {36,    1,    {-1},    {-1}},
    {37,    1,    {-1},    {-1}},
    {38,    1,    {-1},    {-1}},
    {39,    6,    {3 - 1, 6 - 1, 2 - 1, 5 - 1, 4 - 1, 1 - 1},    {0, 5, 5, 1, 2, 2}},
    {40,    1,    {-1},    {-1}},
    {41,    1,    {-1},    {-1}},
    {42,    5,    {4 - 1, 5 - 1, 3 - 1, 6 - 1, 2 - 1},    {3, 3, 1, 5, 5}},
    {43,    6,    {3 - 1, 6 - 1, 2 - 1, 4 - 1, 5 - 1, 1 - 1},    {0, 5, 5, 3, 3, 0}},
    {44,    1,    {-1},    {-1}},
    {45,    1,    {-1},    {-1}},
    {46,    6,    {5 - 1, 3 - 1, 6 - 1, 2 - 1, 4 - 1, 1 - 1},    {2, 1, 5, 5, 3, 2}},
    {47,    5,    {3 - 1, 6 - 1, 2 - 1, 4 - 1, 1 - 1},    {0, 5, 5, 3, 2}},
    {48,    4,    {6 - 1, 2 - 1, 3 - 1, 1 - 1},    {4, 5, 5, 4}},
    {49,    5,    {6 - 1, 2 - 1, 3 - 1, 5 - 1, 1 - 1},    {4, 5, 5, 0, 0}},
    {50,    5,    {6 - 1, 2 - 1, 5 - 1, 3 - 1, 1 - 1},    {4, 5, 1, 1, 4}},
    {51,    4,    {6 - 1, 2 - 1, 5 - 1, 1 - 1},    {4, 5, 1, 0}},
    {52,    1,    {-1},    {-1}},
    {53,    6,    {6 - 1, 2 - 1, 3 - 1, 5 - 1, 4 - 1, 1 - 1},    {4, 5, 5, 0, 2, 2}},
    {54,    1,    {-1},    {-1}},
    {55,    5,    {6 - 1, 2 - 1, 5 - 1, 4 - 1, 1 - 1},    {4, 5, 1, 2, 2}},
    {56,    1,    {-1},    {-1}},
    {57,    1,    {-1},    {-1}},
    {58,    6,    {6 - 1, 2 - 1, 4 - 1, 5 - 1, 3 - 1, 1 - 1},    {4, 5, 3, 3, 1, 4}},
    {59,    5,    {6 - 1, 2 - 1, 4 - 1, 5 - 1, 1 - 1},    {4, 5, 3, 3, 0}},
    {60,    1,    {-1},    {-1}},
    {61,    7,    {5 - 1, 2 - 1, 4 - 1, 1 - 1, 6 - 1, 2 - 1, 3 - 1},    {0, 3, 3, 2, 4, 5, 5}},
    {62,    7,    {5 - 1, 1 - 1, 4 - 1, 2 - 1, 6 - 1, 1 - 1, 3 - 1},    {1, 2, 2, 3, 5, 4, 4}},
    {63,    4,    {6 - 1, 2 - 1, 4 - 1, 1 - 1},    {4, 5, 3, 2}},
    {64,    3,    {4 - 1, 6 - 1, 1 - 1},    {6, 6, 6}},
    {65,    1,    {-1},    {-1}},
    {66,    1,    {-1},    {-1}},
    {67,    1,    {-1},    {-1}},
    {68,    4,    {5 - 1, 4 - 1, 6 - 1, 1 - 1},    {2, 2, 6, 6}},
    {69,    5,    {3 - 1, 5 - 1, 4 - 1, 6 - 1, 1 - 1},    {0, 0, 2, 6, 6}},
    {70,    1,    {-1},    {-1}},
    {71,    6,    {3 - 1, 2 - 1, 5 - 1, 4 - 1, 6 - 1, 1 - 1},    {0, 1, 1, 2, 6, 6}},
    {72,    1,    {-1},    {-1}},
    {73,    1,    {-1},    {-1}},
    {74,    1,    {-1},    {-1}},
    {75,    1,    {-1},    {-1}},
    {76,    5,    {5 - 1, 2 - 1, 4 - 1, 6 - 1, 1 - 1},    {2, 3, 3, 6, 6}},
    {77,    6,    {3 - 1, 5 - 1, 2 - 1, 4 - 1, 6 - 1, 1 - 1},    {0, 0, 3, 3, 6, 6}},
    {78,    6,    {5 - 1, 3 - 1, 2 - 1, 4 - 1, 6 - 1, 1 - 1},    {2, 1, 1, 3, 6, 6}},
    {79,    5,    {3 - 1, 2 - 1, 4 - 1, 6 - 1, 1 - 1},    {0, 1, 3, 6, 6}},
    {80,    4,    {4 - 1, 6 - 1, 3 - 1, 1 - 1},    {6, 6, 4, 4}},
    {81,    5,    {4 - 1, 6 - 1, 3 - 1, 5 - 1, 1 - 1},    {6, 6, 4, 0, 0}},
    {82,    1,    {-1},    {-1}},
    {83,    6,    {4 - 1, 6 - 1, 3 - 1, 2 - 1, 5 - 1, 1 - 1},    {6, 6, 4, 1, 1, 0}},
    {84,    5,    {5 - 1, 4 - 1, 6 - 1, 3 - 1, 1 - 1},    {2, 2, 6, 4, 4}},
    {85,    4,    {5 - 1, 4 - 1, 6 - 1, 3 - 1},    {0, 2, 6, 4}},
    {86,    1,    {-1},    {-1}},
    {87,    5,    {5 - 1, 4 - 1, 6 - 1, 3 - 1, 2 - 1},    {1, 2, 6, 4, 1}},
    {88,    1,    {-1},    {-1}},
    {89,    1,    {-1},    {-1}},
    {90,    1,    {-1},    {-1}},
    {91,    7,    {5 - 1, 4 - 1, 2 - 1, 3 - 1, 6 - 1, 4 - 1, 1 - 1},    {0, 3, 3, 1, 4, 6, 6}},
    {92,    6,    {5 - 1, 2 - 1, 4 - 1, 6 - 1, 3 - 1, 1 - 1},    {2, 3, 3, 6, 4, 4}},
    {93,    5,    {4 - 1, 6 - 1, 3 - 1, 5 - 1, 2 - 1},    {3, 6, 4, 0, 3}},
    {94,    7,    {5 - 1, 3 - 1, 2 - 1, 4 - 1, 6 - 1, 3 - 1, 1 - 1},    {2, 1, 1, 3, 6, 4, 4}},
    {95,    4,    {4 - 1, 6 - 1, 3 - 1, 2 - 1},    {3, 6, 4, 1}},
    {96,    1,    {-1},    {-1}},
    {97,    1,    {-1},    {-1}},
    {98,    1,    {-1},    {-1}},
    {99,    1,    {-1},    {-1}},
    {100,    1,    {-1},    {-1}},
    {101,    1,    {-1},    {-1}},
    {102,    1,    {-1},    {-1}},
    {103,    7,    {3 - 1, 6 - 1, 2 - 1, 5 - 1, 4 - 1, 6 - 1, 1 - 1},    {0, 5, 5, 1, 2, 6, 6}},
    {104,    1,    {-1},    {-1}},
    {105,    1,    {-1},    {-1}},
    {106,    1,    {-1},    {-1}},
    {107,    1,    {-1},    {-1}},
    {108,    1,    {-1},    {-1}},
    {109,    1,    {-1},    {-1}},
    {110,    7,    {2 - 1, 6 - 1, 3 - 1, 5 - 1, 1 - 1, 6 - 1, 4 - 1},    {3, 5, 5, 1, 2, 6, 6}},
    {111,    6,    {3 - 1, 1 - 1, 6 - 1, 4 - 1, 2 - 1, 6 - 1},    {5, 0, 6, 6, 3, 5}},
    {112,    5,    {4 - 1, 6 - 1, 2 - 1, 3 - 1, 1 - 1},    {6, 6, 5, 5, 4}},
    {113,    6,    {4 - 1, 6 - 1, 2 - 1, 3 - 1, 5 - 1, 1 - 1},    {6, 6, 5, 5, 0, 0}},
    {114,    6,    {4 - 1, 6 - 1, 2 - 1, 5 - 1, 3 - 1, 1 - 1},    {6, 6, 5, 1, 1, 4}},
    {115,    5,    {4 - 1, 6 - 1, 2 - 1, 5 - 1, 1 - 1},    {6, 6, 5, 1, 0}},
    {116,    6,    {5 - 1, 4 - 1, 6 - 1, 2 - 1, 3 - 1, 1 - 1},    {2, 2, 6, 5, 5, 4}},
    {117,    5,    {3 - 1, 5 - 1, 4 - 1, 6 - 1, 2 - 1},    {5, 0, 2, 6, 5}},
    {118,    7,    {3 - 1, 5 - 1, 2 - 1, 6 - 1, 4 - 1, 5 - 1, 1 - 1},    {4, 1, 1, 5, 6, 2, 2}},
    {119,    4,    {5 - 1, 4 - 1, 6 - 1, 2 - 1},    {1, 2, 6, 5}},
    {120,    1,    {-1},    {-1}},
    {121,    1,    {-1},    {-1}},
    {122,    7,    {2 - 1, 4 - 1, 5 - 1, 3 - 1, 1 - 1, 4 - 1, 6 - 1},    {5, 3, 3, 1, 4, 6, 6}},
    {123,    6,    {5 - 1, 1 - 1, 4 - 1, 6 - 1, 2 - 1, 4 - 1},    {3, 0, 6, 6, 5, 3}},
    {124,    7,    {4 - 1, 2 - 1, 5 - 1, 1 - 1, 3 - 1, 2 - 1, 6 - 1},    {6, 3, 3, 2, 4, 5, 5}},
    {125,    6,    {5 - 1, 3 - 1, 2 - 1, 6 - 1, 4 - 1, 2 - 1},    {3, 0, 5, 5, 6, 3}},
    {126,    1,    {-1},    {-1}},
    {127,    3,    {4 - 1, 6 - 1, 2 - 1},    {3, 6, 5}},
    {128,    3,    {6 - 1, 4 - 1, 2 - 1},    {7, 7, 7}},
    {129,    1,    {-1},    {-1}},
    {130,    1,    {-1},    {-1}},
    {131,    1,    {-1},    {-1}},
    {132,    1,    {-1},    {-1}},
    {133,    1,    {-1},    {-1}},
    {134,    1,    {-1},    {-1}},
    {135,    1,    {-1},    {-1}},
    {136,    4,    {6 - 1, 4 - 1, 5 - 1, 2 - 1},    {7, 7, 3, 3}},
    {137,    1,    {-1},    {-1}},
    {138,    5,    {6 - 1, 4 - 1, 5 - 1, 3 - 1, 2 - 1},    {7, 7, 3, 1, 1}},
    {139,    6,    {3 - 1, 2 - 1, 6 - 1, 4 - 1, 5 - 1, 1 - 1},    {0, 1, 7, 7, 3, 0}},
    {140,    5,    {5 - 1, 2 - 1, 6 - 1, 4 - 1, 1 - 1},    {2, 3, 7, 7, 2}},
    {141,    6,    {3 - 1, 5 - 1, 2 - 1, 6 - 1, 4 - 1, 1 - 1},    {0, 0, 3, 7, 7, 2}},
    {142,    6,    {5 - 1, 3 - 1, 2 - 1, 6 - 1, 4 - 1, 1 - 1},    {2, 1, 1, 7, 7, 2}},
    {143,    5,    {3 - 1, 2 - 1, 6 - 1, 4 - 1, 1 - 1},    {0, 1, 7, 7, 2}},
    {144,    1,    {-1},    {-1}},
    {145,    1,    {-1},    {-1}},
    {146,    1,    {-1},    {-1}},
    {147,    1,    {-1},    {-1}},
    {148,    1,    {-1},    {-1}},
    {149,    1,    {-1},    {-1}},
    {150,    1,    {-1},    {-1}},
    {151,    1,    {-1},    {-1}},
    {152,    1,    {-1},    {-1}},
    {153,    1,    {-1},    {-1}},
    {154,    1,    {-1},    {-1}},
    {155,    7,    {3 - 1, 6 - 1, 1 - 1, 5 - 1, 4 - 1, 6 - 1, 2 - 1},    {1, 4, 4, 0, 3, 7, 7}},
    {156,    1,    {-1},    {-1}},
    {157,    7,    {1 - 1, 6 - 1, 3 - 1, 5 - 1, 2 - 1, 6 - 1, 4 - 1},    {2, 4, 4, 0, 3, 7, 7}},
    {158,    1,    {-1},    {-1}},
    {159,    6,    {3 - 1, 2 - 1, 6 - 1, 4 - 1, 1 - 1, 6 - 1},    {4, 1, 7, 7, 2, 4}},
    {160,    4,    {3 - 1, 6 - 1, 4 - 1, 2 - 1},    {5, 5, 7, 7}},
    {161,    1,    {-1},    {-1}},
    {162,    5,    {5 - 1, 3 - 1, 6 - 1, 4 - 1, 2 - 1},    {1, 1, 5, 7, 7}},
    {163,    6,    {3 - 1, 6 - 1, 4 - 1, 2 - 1, 5 - 1, 1 - 1},    {0, 5, 7, 7, 1, 0}},
    {164,    1,    {-1},    {-1}},
    {165,    1,    {-1},    {-1}},
    {166,    1,    {-1},    {-1}},
    {167,    7,    {5 - 1, 4 - 1, 1 - 1, 3 - 1, 6 - 1, 4 - 1, 2 - 1},    {1, 2, 2, 0, 5, 7, 7}},
    {168,    5,    {3 - 1, 6 - 1, 4 - 1, 5 - 1, 2 - 1},    {5, 5, 7, 3, 3}},
    {169,    1,    {-1},    {-1}},
    {170,    4,    {6 - 1, 4 - 1, 5 - 1, 3 - 1},    {5, 7, 3, 1}},
    {171,    5,    {3 - 1, 6 - 1, 4 - 1, 5 - 1, 1 - 1},    {0, 5, 7, 3, 0}},
    {172,    6,    {5 - 1, 2 - 1, 3 - 1, 6 - 1, 4 - 1, 1 - 1},    {2, 3, 5, 5, 7, 2}},
    {173,    7,    {5 - 1, 3 - 1, 1 - 1, 4 - 1, 6 - 1, 3 - 1, 2 - 1},    {3, 0, 0, 2, 7, 5, 5}},
    {174,    5,    {5 - 1, 3 - 1, 6 - 1, 4 - 1, 1 - 1},    {2, 1, 5, 7, 2}},
    {175,    4,    {3 - 1, 6 - 1, 4 - 1, 1 - 1},    {0, 5, 7, 2}},
    {176,    5,    {6 - 1, 4 - 1, 2 - 1, 3 - 1, 1 - 1},    {4, 7, 7, 5, 4}},
    {177,    6,    {6 - 1, 4 - 1, 2 - 1, 3 - 1, 5 - 1, 1 - 1},    {4, 7, 7, 5, 0, 0}},
    {178,    6,    {6 - 1, 4 - 1, 2 - 1, 5 - 1, 3 - 1, 1 - 1},    {4, 7, 7, 1, 1, 4}},
    {179,    5,    {6 - 1, 4 - 1, 2 - 1, 5 - 1, 1 - 1},    {4, 7, 7, 1, 0}},
    {180,    1,    {-1},    {-1}},
    {181,    7,    {1 - 1, 4 - 1, 5 - 1, 3 - 1, 2 - 1, 4 - 1, 6 - 1},    {4, 2, 2, 0, 5, 7, 7}},
    {182,    1,    {-1},    {-1}},
    {183,    6,    {5 - 1, 2 - 1, 4 - 1, 6 - 1, 1 - 1, 4 - 1},    {2, 1, 7, 7, 4, 2}},
    {184,    6,    {6 - 1, 4 - 1, 5 - 1, 2 - 1, 3 - 1, 1 - 1},    {4, 7, 3, 3, 5, 4}},
    {185,    7,    {3 - 1, 5 - 1, 1 - 1, 6 - 1, 4 - 1, 5 - 1, 2 - 1},    {5, 0, 0, 4, 7, 3, 3}},
    {186,    5,    {6 - 1, 4 - 1, 5 - 1, 3 - 1, 1 - 1},    {4, 7, 3, 1, 4}},
    {187,    4,    {6 - 1, 4 - 1, 5 - 1, 1 - 1},    {4, 7, 3, 0}},
    {188,    7,    {4 - 1, 1 - 1, 5 - 1, 2 - 1, 3 - 1, 1 - 1, 6 - 1},    {7, 2, 2, 3, 5, 4, 4}},
    {189,    1,    {-1},    {-1}},
    {190,    6,    {5 - 1, 3 - 1, 1 - 1, 6 - 1, 4 - 1, 1 - 1},    {2, 1, 4, 4, 7, 2}},
    {191,    3,    {6 - 1, 4 - 1, 1 - 1},    {4, 7, 2}},
    {192,    4,    {4 - 1, 2 - 1, 6 - 1, 1 - 1},    {6, 7, 7, 6}},
    {193,    1,    {-1},    {-1}},
    {194,    1,    {-1},    {-1}},
    {195,    1,    {-1},    {-1}},
    {196,    5,    {5 - 1, 4 - 1, 2 - 1, 6 - 1, 1 - 1},    {2, 2, 7, 7, 6}},
    {197,    6,    {3 - 1, 5 - 1, 4 - 1, 2 - 1, 6 - 1, 1 - 1},    {0, 0, 2, 7, 7, 6}},
    {198,    1,    {-1},    {-1}},
    {199,    7,    {5 - 1, 2 - 1, 3 - 1, 1 - 1, 6 - 1, 2 - 1, 4 - 1},    {2, 1, 1, 0, 6, 7, 7}},
    {200,    5,    {4 - 1, 5 - 1, 2 - 1, 6 - 1, 1 - 1},    {6, 3, 3, 7, 6}},
    {201,    1,    {-1},    {-1}},
    {202,    6,    {4 - 1, 5 - 1, 3 - 1, 2 - 1, 6 - 1, 1 - 1},    {6, 3, 1, 1, 7, 6}},
    {203,    7,    {5 - 1, 1 - 1, 3 - 1, 2 - 1, 6 - 1, 1 - 1, 4 - 1},    {3, 0, 0, 1, 7, 6, 6}},
    {204,    4,    {5 - 1, 2 - 1, 6 - 1, 1 - 1},    {2, 3, 7, 6}},
    {205,    5,    {3 - 1, 5 - 1, 2 - 1, 6 - 1, 1 - 1},    {0, 0, 3, 7, 6}},
    {206,    5,    {5 - 1, 3 - 1, 2 - 1, 6 - 1, 1 - 1},    {2, 1, 1, 7, 6}},
    {207,    4,    {3 - 1, 2 - 1, 6 - 1, 1 - 1},    {0, 1, 7, 6}},
    {208,    5,    {4 - 1, 2 - 1, 6 - 1, 3 - 1, 1 - 1},    {6, 7, 7, 4, 4}},
    {209,    6,    {4 - 1, 2 - 1, 6 - 1, 3 - 1, 5 - 1, 1 - 1},    {6, 7, 7, 4, 0, 0}},
    {210,    1,    {-1},    {-1}},
    {211,    7,    {3 - 1, 2 - 1, 5 - 1, 1 - 1, 4 - 1, 2 - 1, 6 - 1},    {4, 1, 1, 0, 6, 7, 7}},
    {212,    6,    {5 - 1, 4 - 1, 2 - 1, 6 - 1, 3 - 1, 1 - 1},    {2, 2, 7, 7, 4, 4}},
    {213,    5,    {6 - 1, 3 - 1, 5 - 1, 4 - 1, 2 - 1},    {7, 4, 0, 2, 7}},
    {214,    1,    {-1},    {-1}},
    {215,    6,    {5 - 1, 4 - 1, 2 - 1, 6 - 1, 3 - 1, 2 - 1},    {1, 2, 7, 7, 4, 1}},
    {216,    6,    {4 - 1, 5 - 1, 2 - 1, 6 - 1, 3 - 1, 1 - 1},    {6, 3, 3, 7, 4, 4}},
    {217,    7,    {1 - 1, 5 - 1, 3 - 1, 6 - 1, 2 - 1, 5 - 1, 4 - 1},    {6, 0, 0, 4, 7, 3, 3}},
    {218,    7,    {2 - 1, 3 - 1, 5 - 1, 4 - 1, 1 - 1, 3 - 1, 6 - 1},    {7, 1, 1, 3, 6, 4, 4}},
    {219,    1,    {-1},    {-1}},
    {220,    5,    {5 - 1, 2 - 1, 6 - 1, 3 - 1, 1 - 1},    {2, 3, 7, 4, 4}},
    {221,    4,    {6 - 1, 3 - 1, 5 - 1, 2 - 1},    {7, 4, 0, 3}},
    {222,    6,    {5 - 1, 1 - 1, 3 - 1, 6 - 1, 2 - 1, 3 - 1},    {1, 2, 4, 4, 7, 1}},
    {223,    3,    {6 - 1, 3 - 1, 2 - 1},    {7, 4, 1}},
    {224,    5,    {4 - 1, 2 - 1, 3 - 1, 6 - 1, 1 - 1},    {6, 7, 5, 5, 6}},
    {225,    1,    {-1},    {-1}},
    {226,    6,    {4 - 1, 2 - 1, 5 - 1, 3 - 1, 6 - 1, 1 - 1},    {6, 7, 1, 1, 5, 6}},
    {227,    7,    {3 - 1, 1 - 1, 5 - 1, 2 - 1, 4 - 1, 1 - 1, 6 - 1},    {5, 0, 0, 1, 7, 6, 6}},
    {228,    6,    {5 - 1, 4 - 1, 2 - 1, 3 - 1, 6 - 1, 1 - 1},    {2, 2, 7, 5, 5, 6}},
    {229,    7,    {1 - 1, 3 - 1, 5 - 1, 4 - 1, 2 - 1, 3 - 1, 6 - 1},    {6, 0, 0, 2, 7, 5, 5}},
    {230,    7,    {2 - 1, 5 - 1, 3 - 1, 6 - 1, 1 - 1, 5 - 1, 4 - 1},    {7, 1, 1, 5, 6, 2, 2}},
    {231,    1,    {-1},    {-1}},
    {232,    6,    {4 - 1, 5 - 1, 2 - 1, 3 - 1, 6 - 1, 1 - 1},    {6, 3, 3, 5, 5, 6}},
    {233,    1,    {-1},    {-1}},
    {234,    5,    {4 - 1, 5 - 1, 3 - 1, 6 - 1, 1 - 1},    {6, 3, 1, 5, 6}},
    {235,    6,    {5 - 1, 4 - 1, 1 - 1, 6 - 1, 3 - 1, 1 - 1},    {0, 3, 6, 6, 5, 0}},
    {236,    5,    {5 - 1, 2 - 1, 3 - 1, 6 - 1, 1 - 1},    {2, 3, 5, 5, 6}},
    {237,    6,    {5 - 1, 2 - 1, 3 - 1, 6 - 1, 1 - 1, 3 - 1},    {0, 3, 5, 5, 6, 0}},
    {238,    4,    {5 - 1, 3 - 1, 6 - 1, 1 - 1},    {2, 1, 5, 6}},
    {239,    3,    {3 - 1, 6 - 1, 1 - 1},    {0, 5, 6}},
    {240,    4,    {4 - 1, 2 - 1, 3 - 1, 1 - 1},    {6, 7, 5, 4}},
    {241,    5,    {4 - 1, 2 - 1, 3 - 1, 5 - 1, 1 - 1},    {6, 7, 5, 0, 0}},
    {242,    5,    {4 - 1, 2 - 1, 5 - 1, 3 - 1, 1 - 1},    {6, 7, 1, 1, 4}},
    {243,    4,    {4 - 1, 2 - 1, 5 - 1, 1 - 1},    {6, 7, 1, 0}},
    {244,    5,    {5 - 1, 4 - 1, 2 - 1, 3 - 1, 1 - 1},    {2, 2, 7, 5, 4}},
    {245,    4,    {3 - 1, 5 - 1, 4 - 1, 2 - 1},    {5, 0, 2, 7}},
    {246,    6,    {3 - 1, 1 - 1, 5 - 1, 4 - 1, 2 - 1, 5 - 1},    {1, 4, 2, 2, 7, 1}},
    {247,    3,    {5 - 1, 4 - 1, 2 - 1},    {1, 2, 7}},
    {248,    5,    {4 - 1, 5 - 1, 2 - 1, 3 - 1, 1 - 1},    {6, 3, 3, 5, 4}},
    {249,    6,    {3 - 1, 2 - 1, 5 - 1, 4 - 1, 1 - 1, 5 - 1},    {0, 5, 3, 3, 6, 0}},
    {250,    4,    {4 - 1, 5 - 1, 3 - 1, 1 - 1},    {6, 3, 1, 4}},
    {251,    3,    {4 - 1, 5 - 1, 1 - 1},    {6, 3, 0}},
    {252,    4,    {5 - 1, 2 - 1, 3 - 1, 1 - 1},    {2, 3, 5, 4}},
    {253,    3,    {3 - 1, 5 - 1, 2 - 1},    {5, 0, 3}},
    {254,    3,    {5 - 1, 3 - 1, 1 - 1},    {2, 1, 4}},
    {255,    1,    {-1},    {-1}}
  };

TVertex::TVertex()
{
  wh_[0] = wh_[1] = wh_[2] = count_ = 0;
  for( int i = 0; i < 14; ++i )
    {
    neighb_[i] = 0;
    }
}

TVertex::TVertex(int wh[3], int count, int neighb[14])
{
  wh_[0] = wh[0]; wh_[1] = wh[1]; wh_[2] = wh[2];
  count_ = count;
  for( int i = 0; i < count; ++i )
    {
    neighb_[i] = neighb[i];
    }
}

int operator==(const TVertex& v1, const TVertex& v2)
{
  if( v2.count_ != v1.count_ )
    {
    return 0;
    }

  int result = (v1.wh_[0] == v2.wh_[0] && v1.wh_[1] == v2.wh_[1] && v1.wh_[2] == v2.wh_[2]);
  for( int i = 0; i < v2.count_; ++i )
    {
    result = result && (v1.neighb_[i] == v2.neighb_[i]);
    }

  return result;
}

std::ostream & operator<<(std::ostream& os, const TVertex& v)
{
  os << "{{" << v.wh_[0] << ", " << v.wh_[1] << ", " << v.wh_[2] << "}, {";
  for( int i = 0; i < v.count_; ++i )
    {
    os << v.neighb_[i];
    if( i != v.count_ - 1 )
      {
      os << ", ";
      }
    }
  os << "}}";
  return os;
}

void TVertexArray::init(const TVertex* ar, int sz)
{
  ia_ = new TVertex[size_ = sz];
  TVertex defaultVertex;
  for( int ix = 0; ix < size_; ++ix )
    {
    ia_[ix] = (ar != 0) ? ar[ix] : defaultVertex;
    }
}

TVertexArray & TVertexArray::operator=(const TVertexArray& iA)
{
  if( this == &iA )
    {
    return *this;
    }
  delete ia_;
  init( iA.ia_, iA.size_ );
  return *this;
}

int TVertexArray::find(TVertex val) const
{
  for( int i = 0; i < size_; ++i )
    {
    if( val == ia_[i] )
      {
      return i;
      }
    }
  return -1;
}

void TVertexArray::print(std::ostream& os) const
{
  for( int i = 0; i < size_; ++i )
    {
    os << ia_[i];
    if( i != (size_ - 1) )
      {
      os << ",\n";
      }
    }
  os << "\n";
}

std::ostream & operator<<(std::ostream& os, const TVertexArray& ar)
{
  ar.print(os);
  return os;
}

TVertexList::~TVertexList()
{
  if( last_ )
    {
    TVertexItem* ptr = last_->next_;
    last_->next_ = 0;
    while( ptr )
      {
      TVertexItem* tmp = ptr;
      ptr = ptr->next_;
      delete tmp;
      }
    }
}

TVertexItem * TVertexList::search(TVertex val) const
{
  TVertexItem* p = 0;

  forall_vertexlistitems(p, *this)
  if( p->val_ == val )
    {
    break;
    }

  return p;
}

int TVertexList::contains(TVertex val) const
{
  TVertexItem* p = 0;

  forall_vertexlistitems(p, *this)
  if( p->val_ == val )
    {
    return 1;
    }

  return 0;
}

int TVertexList::size() const
{
  int          i = 0;
  TVertexItem* a;

  forall_vertexlistitems(a, *this)
  i++;

  return i;
}

void TVertexList::insert(TVertex val)
{
  TVertexItem* a = new TVertexItem(val);

  if( last_ )
    {
    a->next_ = last_->next_;
    }
  else
    {
    last_ = a;
    }
  last_->next_ = a;
}

void TVertexList::append(TVertex val)
{
  TVertexItem* a = new TVertexItem(val);

  if( last_ )
    {
    a->next_ = last_->next_;
    last_ = last_->next_ = a;
    }
  else
    {
    last_ = a->next_ = a;
    }
}

TVertex TVertexList::pop()
{

  TVertexItem* f = last_->next_;

  if( f == last_ )
    {
    last_ = 0;
    }
  else
    {
    last_->next_ = f->next_;
    }

  // this code makes no sense, and
  // has no side effects outside this
  // method.
  // static TVertexItem * last = NULL;
  // if( last )
  //   {
  //   delete last;
  //   }

  // last = f;

  return f->val_;
}

void TVertexList::remove(TVertexItem* it)
{
  TVertexItem* before = it;

  while( before->next_ != it )
    {
    before = before->next_;
    }

  before->next_ = it->next_;
  if( last_ == it )
    {
    last_ = before;
    }
  if( before == it )
    {
    last_ = 0;
    }
  delete it;
}

void TVertexList::insert_after(TVertex val, TVertexItem* it)
{
  TVertexItem* a = new TVertexItem(val);

  a->next_ = it->next_;
  it->next_ = a;
  if( it == last_ )
    {
    last_ = a;
    }
}

void TVertexList::print(std::ostream& os) const
{
  int _first = 1;

  if( !empty() )
    {
    for( TVertexItem* ptr = last_->next_; ; ptr = ptr->next_ )
      {
      if( _first )
        {
        _first = 0;
        }
      else
        {
        os << ", \n";
        }
      os << ptr->val_;
      if( ptr == last_ )
        {
        break;
        }
      }
    }
  os << std::endl;
}

std::ostream & operator<<(std::ostream& os, const TVertexList& li)
{
  li.print(os);
  return os;
}

TSurfaceNet::TSurfaceNet(TVoxelVolume& vol, int thresh)
{
  // build a surface net using a TNetExtractor object
  thresh_ = (unsigned char) thresh;
  va_ = 0;
  this->vol2net(vol);
}

void TSurfaceNet::read(std::istream& is)
{
  char        ch;
  int         wh[3];
  int         count;
  int         neighb[14];
  TVertexList vl;

  is >> ch;
  for( ; ; )
    {
    is >> ch;
    if( ch == '}' )
      {
      break;
      }

    is >> ch; is >> wh[0];
    is >> ch; is >> wh[1];
    is >> ch; is >> wh[2];
    is >> ch; is >> ch; is >> ch;
    for( count = 0; ; count++ )
      {
      is >> neighb[count];
      is >> ch;
      if( ch == '}' )
        {
        count++;
        break;
        }
      }
    TVertex v(wh, count, neighb);
    vl.append(v);
    is >> ch;     // '}'
    is >> ch;     // ','
    if( ch == '}' )
      {
      break;
      }
    }
  int i = 0;
  int L = vl.length();
  va_ = new TVertexArray(L);
  while( !vl.empty() )
    {
    TVertex v = vl.pop();
    (*va_)[i] = v;
    ++i;
    }
}

void TSurfaceNet::print(std::ostream& os) const
{
  os << "{" << std::endl;
  (*va_).print(os);
  os << "}" << std::endl;
}

int TSurfaceNet::GetIndex(const TPoint3D& pt) const
{
  for( int i = 0; i < va_->size(); ++i )
    {
    if( (*va_)[i].GetCoords3D() == pt )
      {
      return i;
      }
    }

  return -1;
}

int TSurfaceNet::nface() const
{
  // count faces
  int nfaces = 0;

  for( int i = 0; i < va_->size(); ++i )
    {
    TVertex v = (*va_)[i];
    for( int j = 0; j + 1 < v.count_; j += 2 )
      {
      int second = (j + 2) % v.count_;
      if( v.neighb_[j] > i &&
          v.neighb_[j + 1] > i &&
          v.neighb_[second] > i )
        {
        nfaces++;
        }
      }
    }
  return nfaces;
}

void TSurfaceNet::vol2net(TVoxelVolume& vol)
{
  vol.SetBoundary(0);
  vol.Binarize(thresh_);

  TNetExtractor ne(&vol);
  TVertexList*  vl;
  vl = ne.extractnet();
  int i = 0;
  int L = vl->length();
  va_ = new TVertexArray(L);
  while( !vl->empty() )
    {
    TVertex v = vl->pop();
    (*va_)[i] = v;
    ++i;
    }

  delete vl;
}

std::ostream & operator<<(std::ostream& os, const TSurfaceNet& sn)
{
  sn.print(os);
  return os;
}

int TNetExtractor::direct_translate(int dir, int ne)
{
  int trne = tr_direct[dir][ne];

  return trne;
}

#define DIR(D1, D2) ( ( (dir1 == D1) && (dir2 == D2) ) || ( (dir1 == D2) && (dir2 == D1) ) )
int TNetExtractor::diag_translate(int dir1, int dir2, int ne)
{
  // ugly (we could do better)
  int trne = 0;

  if DIR(S, E) {
    switch( ne )
      {
      case 1: trne = 2; break;
      case 5: trne = 6; break;
      case 3: trne = -1; break;
      }
    }
  else if DIR(E, N) {
    switch( ne )
      {
      case 3: trne = 0; break;
      case 7: trne = 4; break;
      }
    }
  else if DIR(N, W) {
    switch( ne )
      {
      case 6: trne = 5; break;
      case 2: trne = 1; break;
      }
    }
  else if DIR(W, S) {
    switch( ne )
      {
      case 4: trne = 7; break;
      case 0: trne = 3; break;
      }
    }
  else if DIR(T, S) {
    switch( ne )
      {
      case 4: trne = 2; break;
      case 5: trne = 3; break;
      }
    }
  else if DIR(S, B) {
    switch( ne )
      {
      case 0: trne = 6; break;
      case 1: trne = 7; break;
      }
    }
  else if DIR(B, N) {
    switch( ne )
      {
      case 2: trne = 4; break;
      case 3: trne = 5; break;
      }
    }
  else if DIR(N, T) {
    switch( ne )
      {
      case 6: trne = 0; break;
      case 7: trne = 1; break;
      }
    }
  else if DIR(E, T) {
    switch( ne )
      {
      case 5: trne = 0; break;
      case 7: trne = 2; break;
      }
    }
  else if DIR(T, W) {
    switch( ne )
      {
      case 4: trne = 1; break;
      case 6: trne = 3; break;
      }
    }
  else if DIR(W, B) {
    switch( ne )
      {
      case 0: trne = 5; break;
      case 2: trne = 7; break;
      }
    }
  else if DIR(B, E) {
    switch( ne )
      {
      case 1: trne = 4; break;
      case 3: trne = 6; break;
      }
    }
  return trne;
}

void TNetExtractor::encode(int nx, int ny, int /*UNUSED nz*/, int& number,
                           unsigned char* nbc, numentry* num, int z)
{
  for( int y = 0; y < ny; y++ )
    {
    for( int x = 0; x < nx; x++ )
      {
      unsigned char code = 0;
      for( int i = 0; i < 8; i++ )
        {
        code |= (*vol_)(x + i % 2, y + i / 2 % 2, z + i / 4) & 1 << i;
        }
      nbc[x + nx * y] = code;
      numentry* num_act = &num[x + nx * y];

      if( code == 126 )
        {
        num_act->nums[3] = num_act->nums[5] = num_act->nums[6] = number;
        number++;
        num_act->nums[1] = num_act->nums[2] = num_act->nums[4] = number;
        number++;
        }

      else if( code == 189 )
        {
        num_act->nums[0] = num_act->nums[3] = num_act->nums[5] = number;
        number++;
        num_act->nums[2] = num_act->nums[4] = num_act->nums[7] = number;
        number++;
        }

      else if( code == 219 )
        {
        num_act->nums[0] = num_act->nums[3] = num_act->nums[6] = number;
        number++;
        num_act->nums[1] = num_act->nums[4] = num_act->nums[7] = number;
        number++;
        }

      else if( code == 231 )
        {
        num_act->nums[0] = num_act->nums[5] = num_act->nums[6] = number;
        number++;
        num_act->nums[1] = num_act->nums[2] = num_act->nums[7] = number;
        number++;
        }

      else
        {
        for( int i = 0; i < pt1[code].count; i++ )
          {
          unsigned char nc_act = pt1[code].nbcs[i];
          if( nc_act )
            {
            for( int j = 0; j < 8; j++ )
              {
              if( nc_act & (1 << j) )
                {
                num_act->nums[j] = number;
                }
              }
            number++;
            }
          }
        }
      }
    }
}

TVertexList * TNetExtractor::extractnet()
{
  int i, j, k, x, y, z, xy;
  int number = 0;
  int nx = vol_->Nx();
  int ny = vol_->Ny();
  int nz = vol_->Nz();

  int z_tab[]  = { 0, 0, 0, 0, -1, 1 };
  int xy_tab[] = { -1, 1, -nx, nx, 0, 0 };

  numentry* num[3];

  num[0] = new numentry[nx * ny * 3];
  num[1] = num[0] + nx * ny;
  num[2] = num[1] + nx * ny;
  numentry* num_remember = num[0];
  // dbg
  for( i = 0; i < nx * ny * 3; i++ )
    {
    for( j = 0; j < 8; j++ )
      {
      num[0][i].nums[j] = -1;
      }
    }

  unsigned char *nbc_this, *nbc_next, *nbc_remember;
  nbc_this = new unsigned char[nx * ny * 2];
  nbc_remember =  nbc_this;
  nbc_next = nbc_this + nx * ny;

  encode(nx, ny, nz, number, nbc_next, num[2], 0);

  TVertexList* vl = new TVertexList;  // collect vertices in this list
  for( z = 0; z < nz - 1; z++ )
    {

    numentry*      help_i = num[0]; num[0] = num[1]; num[1] = num[2]; num[2] = help_i;
    unsigned char* help_u = nbc_this; nbc_this = nbc_next; nbc_next = help_u;

    if( z < nz - 2 )
      {
      encode(nx, ny, nz, number, nbc_next, num[2], z + 1);
      }
    for( y = 0; y < ny - 1; y++ )
      {
      for( x = 0; x < nx - 1; x++ )
        {

        // nc is the nbc as encounterd in the input data volume
        const unsigned char nc=nbc_this[xy = x + nx * y];
        if( nc )
          {
          for( i = 0; i < pt1[nc].count; i++ )
            {

            // according  to table1, we split nc into pieces to get an "actual" nbc
            unsigned char nc_act = pt1[nc].nbcs[i];
            if( nc_act )
              {
              int wh_act[3];
              int count_act = 0;
              int neighb_act[14];
              wh_act[0] = x + 1; wh_act[1] = y + 1; wh_act[2] = z + 1;

              int count2 = pt2[nc_act].count;
              // the values where to look for the neighbor's numbers in the num array are precomputed
              // and stored in table pt2
              for( k = 0; k < count2; k++ )
                {

                int dir1 = pt2[nc_act].dir[k];
                int dir2 = pt2[nc_act].dir[(k + 1) % count2];
                int ne1  = pt2[nc_act].ne[k];
                int ne2  = pt2[nc_act].ne[(k + 1) % count2];

                int t_ne1 = direct_translate(dir1, ne1);
                int num_act = num[1 + z_tab[dir1]][xy + xy_tab[dir1]].nums[t_ne1];
                neighb_act[count_act++] = num_act;

                int      t_ne2 = diag_translate(dir1, dir2, ne2);
                // numentry dbg = num[1 + z_tab[dir1] + z_tab[dir2]][xy + xy_tab[dir1] + xy_tab[dir2]];
                num_act = num[1 + z_tab[dir1] + z_tab[dir2]]
                  [xy + xy_tab[dir1] + xy_tab[dir2]].nums[t_ne2];
                neighb_act[count_act++] = num_act;
                }

              // save vertex
              TVertex v(wh_act, count_act, neighb_act);
              vl->append(v);

              } // if(nc_act)
            }
          }
        }
      }
    }

  delete [] nbc_remember;
  delete [] num_remember;;

  return vl;
}
